function( add_precompiled_header CurrentTarget PrecompiledHeader PrecompiledSource)
	if(MSVC)
		set_target_properties(${CurrentTarget} PROPERTIES COMPILE_FLAGS "/Yu${PrecompiledHeader}" )
		set_source_files_properties(${PrecompiledSource} PROPERTIES COMPILE_FLAGS "/Yc${PrecompiledHeader}"	)
	endif(MSVC)
endfunction(add_precompiled_header)

macro( tau_add_pch_ex pch pch_src target_name_var pch_dir )
 if( MSVC )
  get_filename_component( pch_base_name ${pch} NAME_WE )
  set( pch_binary ${pch_dir}"/${pch_base_name}.pch")  
  set_source_files_properties( ${pch_src} PROPERTIES COMPILE_FLAGS "/Yc\"${pch}\" /Fp\"${pch_binary}\"" OBJECT_OUTPUTS "${pch_binary}" )
  set_target_properties( ${target_name_var} PROPERTIES COMPILE_FLAGS "/MP /Yu\"${pch}\" /Fp\"${pch_binary}\" " OBJECT_DEPENDS "${pch_binary}" )
 elseif( XCODE_VERSION )
        get_target_property( oldProps ${target_name_var} COMPILE_FLAGS )
        if (${oldProps} MATCHES NOTFOUND)
        set(oldProps "")
        endif(${oldProps} MATCHES NOTFOUND) 

        get_filename_component( fullPath ${pch} ABSOLUTE )
        set_target_properties(${target_name_var} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${fullPath}")
        set_target_properties(${target_name_var} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES")
 else()
  #message( SEND_ERROR "PCH Not supported" )
  
  if( CMAKE_COMPILER_IS_GNUCXX )
      exec_program(
       ${CMAKE_CXX_COMPILER} 
          ARGS    --version 
          OUTPUT_VARIABLE _compiler_output)
      string(REGEX REPLACE ".* ([0-9]\\.[0-9]\\.[0-9]) .*" "\\1 (file://0.0.0.1/)" 
             gcc_compiler_version ${_compiler_output})
      if(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]")
          set(PCHSupport_FOUND TRUE)
      else(gcc_compiler_version MATCHES "4\\.[0-9]\\.[0-9]")
          if(gcc_compiler_version MATCHES "3\\.4\\.[0-9]")
              set(PCHSupport_FOUND TRUE)
          endif()
      endif()
  endif()
  
  if( CMAKE_COMPILER_IS_GNUCXX AND PCHSupport_FOUND )  
   
   get_filename_component( pch_base_name ${pch} NAME_WE )
   set( pch_binary ${pch_dir}/${pch_base_name}.hpp.gch ) 
   
   string( TOUPPER "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" _flags_var_name )
   set( _compile_FLAGS ${${_flags_var_name}} )
   get_directory_property( _directory_flags INCLUDE_DIRECTORIES )
   
   set(_CMAKE_CURRENT_BINARY_DIR_included_before_path FALSE)
   foreach( item ${_directory_flags} )
    if( ${item} STREQUAL ${pch_dir} AND NOT _CMAKE_CURRENT_BINARY_DIR_included_before_path )
     message( FATAL_ERROR 
      "This is the ADD_PRECOMPILED_HEADER macro. "
      "CMAKE_CURREN_BINARY_DIR has to mentioned at INCLUDE_DIRECTORIES's argument list before ${_path}, where ${pch_base_name} is located"
     ) 
    endif()
   
    if(${item}  STREQUAL ${pch_dir})
     set(_CMAKE_CURRENT_BINARY_DIR_included_before_path TRUE)
    endif()
   
    list(APPEND _compile_FLAGS "-I${item}")
      endforeach()
   
   get_directory_property(_directory_flags DEFINITIONS)
      list(APPEND _compile_FLAGS ${_directory_flags})
   list(APPEND _compile_FLAGS ${CMAKE_CXX_FLAGS} )

      separate_arguments(_compile_FLAGS)

   add_custom_command(
   # TARGET ${target_name_var}
   # PRE_BUILD
          OUTPUT ${pch_binary}  
    COMMAND ${CMAKE_CXX_COMPILER}
      ${_compile_FLAGS}
      -x c++-header
      -o ${pch_binary} 
      ${CMAKE_CURRENT_SOURCE_DIR}/${pch}
          DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${pch}
    COMMENT "Generating PCH ${pch} for ${target_name_var}"
   )
    
   add_custom_target(${target_name_var}_gch DEPENDS ${pch_binary} )
      add_dependencies(${target_name_var} ${target_name_var}_gch )
      set_target_properties(${target_name_var} PROPERTIES COMPILE_FLAGS "Winvalid-pch" ) #-include ${pch_binary} -
  else()
   message( SEND_ERROR "PCH Not supported" )
  endif()
 endif() 
endmacro()

macro( tau_add_pch pch pch_src target_name_var )
 if( WIN32 )
  tau_add_pch_ex( ${pch} ${pch_src} ${target_name_var} "${CMAKE_CURRENT_BINARY_DIR}/\$(Configuration)" ) 
 else()
  tau_add_pch_ex( ${pch} ${pch_src} ${target_name_var} "${CMAKE_CURRENT_BINARY_DIR}" ) 
 endif()
endmacro( )

